package com.suishoupai.xmb.service;

import com.alibaba.druid.util.StringUtils;
import com.suishoupai.xmb.entity.AuthImageCode;
import com.suishoupai.xmb.exception.XmbException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@Service
public class VerificationCodeService {
    @Value("${auth.verification.code.timeout}")
    private int authVerificationCodeTimeout;

    private static final String AUTH_IMAGE_CODE_SESSION_KEY = "a_i_c_s_k";

    /**
     * 生成图片验证码
     *
     * @param response 将图片通过response输出
     * @param session  存放验证码用于下次验证
     * @return
     * @throws XmbException
     */
    public void fillImageCode(HttpServletResponse response, HttpSession session) throws XmbException {
        int width = 63;
        int height = 37;
        Random random = new Random();
        //设置response头信息
        //禁止缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        //生成缓冲区image类
        BufferedImage image = new BufferedImage(width, height, 1);
        //产生image类的Graphics用于绘制操作
        Graphics g = image.getGraphics();
        //Graphics类的样式
        g.setColor(this.getRandColor(200, 250));
        g.setFont(new Font("Times New Roman", 0, 28));
        g.fillRect(0, 0, width, height);
        //绘制干扰线
        for (int i = 0; i < 40; i++) {
            g.setColor(this.getRandColor(130, 200));
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(12);
            int y1 = random.nextInt(12);
            g.drawLine(x, y, x + x1, y + y1);
        }

        //绘制字符
        String strCode = "";
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            strCode = strCode + rand;
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(rand, 13 * i + 6, 28);
        }

        g.dispose();
        try {
            ImageIO.write(image, "JPEG", response.getOutputStream());
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw XmbException.newError(e.getMessage());
        }

        session.setAttribute(AUTH_IMAGE_CODE_SESSION_KEY, new AuthImageCode(strCode, System.currentTimeMillis()));
    }

    /**
     * 验证图文验证码
     *
     * @return
     */
    public void validateImageCode(String code, HttpSession session) throws XmbException {
        AuthImageCode authImageCode = (AuthImageCode) session.getAttribute(AUTH_IMAGE_CODE_SESSION_KEY);
        session.removeAttribute(AUTH_IMAGE_CODE_SESSION_KEY);//验证一次过后就清除。
        if (StringUtils.isEmpty(code)) {
            throw XmbException.newVerificationError("请输入验证码。");
        }
        if (authImageCode == null) {
            throw XmbException.newVerificationError("请获取验证码。");
        }
        if (System.currentTimeMillis() - authImageCode.getTime() >= authVerificationCodeTimeout) {
            throw XmbException.newVerificationError("请重新获取验证码。");
        }
        if (!code.equals(authImageCode.getCode())) {
            throw XmbException.newVerificationError("验证码错误。");
        }
    }

    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
}
